package bancosys.tec.job.jms;

import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.ObjectMessage;

import jmine.tec.batch.BatchController;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import bancosys.tec.job.Job;

/**
 * @author takeshi
 */
public class JobExecutorMessageListener implements MessageListener {
    private static Log log = LogFactory.getLog(JobExecutorMessageListener.class);

    private BatchController controller;

    /**
     * Devolve o KernelController.
     * 
     * @return o KernelController.
     */
    public BatchController getBatchController() {
        return this.controller;
    }

    /**
     * Define o KernelController.
     * 
     * @param kernelController kernelController
     */
    public void setBatchController(BatchController kernelController) {
        this.controller = kernelController;
    }

    /**
     * Chamado pelo container para tratar as mensagens de JMS.
     * 
     * @param msg mensagem jms
     */
    public void onMessage(Message msg) {
        Job job;
        try {
            if (!(msg instanceof ObjectMessage)) {
                log.error(Thread.currentThread() + " wrong message type. Message " + msg.getJMSMessageID() + " is not an ObjectMessage.");
                return;
            }

            ObjectMessage objectMessage = (ObjectMessage) msg;
            Object object = objectMessage.getObject();
            if (!(object instanceof Job)) {
                log.error(Thread.currentThread() + " wrong message type. Message " + msg.getJMSMessageID() + " does not contain a Job.");
                return;
            }
            job = (Job) object;
        } catch (Throwable e) {
            log.error(Thread.currentThread() + " error acquiring job.", e);
            return;
        }

        try {
            log.debug(Thread.currentThread() + " executing job[" + job.getId() + "]");
            this.controller.clearBatchExecutionContext();
            this.preProcessJob(job);
            job.execute(this.getBatchController().getBatchExecutionContext());
        } catch (Throwable e) {
            log.error(Thread.currentThread() + " error processing job[" + job.getId() + "]", e);
        }
    }

    /**
     * Método para as classes derivadas sobreescrever para pré-processar o job
     * 
     * @param job job
     */
    protected void preProcessJob(Job job) {
        // método template p/ pre-processar o job.
    }
}
